package org.jeecg.modules.car.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sun.mail.imap.protocol.ID;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.SsoUtil;
import org.jeecg.common.util.StringUtils;
import org.jeecg.enums.PayModeEnum;
import org.jeecg.entity.car.CarDerateDetails;
import org.jeecg.enums.PayStatusEnum;
import org.jeecg.model.car.reqvo.CarDayReportReqVo;
import org.jeecg.model.car.respvo.CarDayReportRespVo;
import org.jeecg.modules.car.entity.CarMerchant;
import org.jeecg.modules.car.entity.CarMerchantOrder;
import org.jeecg.modules.car.entity.CarPayNotify;
import org.jeecg.modules.car.mapper.CarMerchantOrderMapper;
import org.jeecg.modules.car.service.ICarMerchantOrderService;
import org.jeecg.modules.car.service.ICarMerchantService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * @Description: 商户充值明细
 * @Author: jeecg-boot
 * @Date:   2020-10-21
 * @Version: V1.0
 */
@Service
@Slf4j
public class CarMerchantOrderServiceImpl extends ServiceImpl<CarMerchantOrderMapper, CarMerchantOrder> implements ICarMerchantOrderService {
    private final Queue<String> payQueue = new ConcurrentLinkedQueue<String>();
    @Autowired
    private CarMerchantOrderMapper carMerchantOrderMapper;
    @Autowired
    private ICarMerchantService carMerchantService;


    @Transactional(readOnly = false)
    public Integer carPayNotify( CarPayNotify stu) {
        log.info("商家支付销账接受参数:{}",stu);
        Integer result = 0;
        CarMerchantOrder order =  carMerchantOrderMapper.getOrderBySn(stu.getOrderId());
        //通知成功
        if (order == null) {
            return result;//销账失败
        }
        //已支付。直接结束
        if (order.getPayStatus().intValue() == PayStatusEnum.PAY_STATUS_YES.getCode().intValue()) {
            return result;
        }
        //判断在队列中是否存在 -- 防止重复回调
        if (payQueue.contains(stu.getOrderId())) {
            log.warn("账单支付中transNo:{},sn:{}",stu.getTransNo(),stu.getOrderId());
            return result;
        }
        payQueue.add(stu.getOrderId());
        try {
            CarMerchant carMerchant =  carMerchantService.getById(order.getMerchantId());
            //更新订单状态
            int updateStatus = carMerchantOrderMapper.updatePayStatus(order.getSn(),DateUtils.str2Date(stu.getPaymentTime(),DateUtils.yyyymmddhhmmss),stu.toString());
            log.info("商家支付更新订单状态结果:{}",updateStatus);
            if (carMerchant != null && updateStatus == 1){
                BigDecimal remainAmount = carMerchant.getRemainAmount() == null? BigDecimal.ZERO:carMerchant.getRemainAmount();
                carMerchant.setRemainAmount(remainAmount.add(order.getActualAmount()));
                //更新商户余额
                carMerchantService.updateRemainAmount(carMerchant);
            } else {
                log.warn("商家支付销账未获取到商户信息:transNo:{}",stu.getTransNo());
            }

        } catch (Exception e) {
            log.error("商家支付销账更新订单表异常:{}",e);
        } finally {
            payQueue.remove(stu.getOrderId());
        }
        return result;
    }

    @Override
    public List<CarMerchantOrder> findByMerChantById(String merchantId) {
        return carMerchantOrderMapper.findByMerChantById(merchantId);
    }

    @Override
    public List<CarMerchantOrder> findPage(Page<CarMerchantOrder> page, CarMerchantOrder carMerchantOrder) {
        carMerchantOrder.setTenantId(SsoUtil.getLoginUser().getTenantId());
        return carMerchantOrderMapper.findPage(page,carMerchantOrder);
    }

    /**
     * 商户线下退款
     * @param carMerchantOrder
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result refund(CarMerchantOrder carMerchantOrder) {
        //查询商户信息
        CarMerchant carMerchant = carMerchantService.getById(carMerchantOrder.getMerchantId());
        if (carMerchant == null) {
            return Result.error("未查询到商户信息");
        }
        CarMerchantOrder order = this.getById(carMerchantOrder.getId());
        if (order == null){
            return Result.error("未查询到当前订单信息");
        }
        if(!order.getPayMode().equals(PayModeEnum.PAY_MODE_OFFLINE.getCode()) || order.getPayStatus() != 1){
            return Result.error("当前状态订单不允许操作！");
        }
        //积分订单
        if (order.getOrderType() == 1){
            carMerchant.setDonateAmount(carMerchant.getDonateAmount().subtract(order.getActualAmount()));
        }else {
            //更新商户余额  = 商户余额 - 充值时实际到账金额
            carMerchant.setRemainAmount(carMerchant.getRemainAmount().subtract(order.getActualAmount()));
        }
        //设置订单信息
        order.setPayStatus(PayStatusEnum.PAY_STATUS_ED.getCode());
        this.updateById(order);
        //增加退款订单信息
        CarMerchantOrder refundOrder = new CarMerchantOrder();
        refundOrder.setPayStatus(PayStatusEnum.PAY_STATUS_REFUND.getCode());
        refundOrder.setOrderType(order.getOrderType());
        refundOrder.setProjectId(order.getProjectId());
        refundOrder.setMerchantId(order.getMerchantId());
        refundOrder.setSn(order.getSn()+"refund");
        refundOrder.setTenantId(SsoUtil.getLoginUser().getTenantId());
        refundOrder.setPayType(order.getPayType());
        refundOrder.setPayMode(order.getPayMode());
        refundOrder.setPayAmount(order.getPayAmount().negate());
        refundOrder.setDiscountAmount(order.getDiscountAmount().negate());
        refundOrder.setActualAmount(order.getActualAmount().negate());
        refundOrder.setPayTime(new Date());
        refundOrder.setChargeStatus(1);
        if (order.getOrderType() == 1){
            refundOrder.setBalance(carMerchant.getDonateAmount());
        }else {
            refundOrder.setBalance(carMerchant.getRemainAmount());
        }
        //更新商户余额
        carMerchantService.updateById(carMerchant);
        //添加退款记录
        carMerchantOrderMapper.insert(refundOrder);
        return Result.ok("退款成功！");
    }

    @Override
    public List<CarDayReportRespVo> findGroupList(CarDayReportReqVo carDayReportReqVo) {
        return carMerchantOrderMapper.findGroupList(carDayReportReqVo);
    }

    @Override
    public List<CarMerchantOrder> findMerchantOrderList(Page<CarMerchantOrder> page, CarMerchant carMerchant) {
        return carMerchantOrderMapper.findMerchantOrderList(page, carMerchant);
    }
}
